package com.xzj.getway.util;

import com.xzj.admin.base.domain.gateway.XzjRouteDefinition;
import com.xzj.admin.base.domain.gateway.XzjRouterConfigDefinition;
import com.xzj.getway.constants.GatewayConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.web.util.UriComponentsBuilder;

import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;

/**
 * @program: xzj-admin
 * @ClassName: GateWayUtil
 * @description: 网关方法层
 * @author: XiaZunJun
 * @create: 2024-10-11 11:34
 */
@Slf4j
public class GateWayUtil {

    private static final Map<String, BiConsumer<Map,XzjRouterConfigDefinition>> ROUTER_CONFIG_FUN_MAP = new HashMap<>();

    static {
        ROUTER_CONFIG_FUN_MAP.put(GatewayConstants.ROUTER_PREDICATES, GateWayUtil::buildPredicateDefinition);
        ROUTER_CONFIG_FUN_MAP.put(GatewayConstants.ROUTER_FILTERS, GateWayUtil::buildFilterDefinition);
    }

    public static RouteDefinition buildRouteDefinition(XzjRouteDefinition xzjRouter){
        RouteDefinition definition = new RouteDefinition();
        definition.setId(xzjRouter.getId());
        definition.setOrder(xzjRouter.getOrder());
        //设置断言
        List<XzjRouterConfigDefinition> configDefinitions = new ArrayList<>();
        configDefinitions.addAll(xzjRouter.getPredicatesConfig());
        configDefinitions.addAll(xzjRouter.getFiltersConfig());
        Map<String, PredicateDefinition> pdDefinedMap = new HashMap<>();
        Map<String, FilterDefinition> filtersDefinedMap = new HashMap<>();
        for(XzjRouterConfigDefinition configDefinition: configDefinitions){
            if(ROUTER_CONFIG_FUN_MAP.containsKey(configDefinition.getConfigType())){
                ROUTER_CONFIG_FUN_MAP.get(configDefinition.getConfigType()).accept(configDefinition.getConfigType().equals(GatewayConstants.ROUTER_PREDICATES)?pdDefinedMap:filtersDefinedMap, configDefinition);
            }
        }
        for (PredicateDefinition predicateDefinition : pdDefinedMap.values()) {
            definition.getPredicates().add(predicateDefinition);
        }
        for(FilterDefinition filterDefinition: filtersDefinedMap.values()){
            definition.getFilters().add(filterDefinition);
        }
        URI uri;
        if(xzjRouter.getUri().startsWith("http")){
            uri = UriComponentsBuilder.fromHttpUrl(xzjRouter.getUri()).build().toUri();
        }else{
            uri = URI.create(xzjRouter.getUri());
        }
        definition.setUri(uri);
        return definition;
    }

    private static void buildPredicateDefinition(Map<String, PredicateDefinition> definedMap,XzjRouterConfigDefinition configDefinition){
        PredicateDefinition predicate;
        if(definedMap.containsKey(configDefinition.getConfigName())){
            predicate = definedMap.get(configDefinition.getConfigName());
        }else{
            predicate = new PredicateDefinition();
            predicate.setName(configDefinition.getConfigName());
            definedMap.put(configDefinition.getConfigName(), predicate);
        }
        predicate.getArgs().put(configDefinition.getConfigKey(), configDefinition.getConfigValue());
    }

    private static void buildFilterDefinition(Map<String, FilterDefinition> definedMap,XzjRouterConfigDefinition configDefinition){
        FilterDefinition filter;
        if(definedMap.containsKey(configDefinition.getConfigName())){
            filter = definedMap.get(configDefinition.getConfigName());
        }else{
            filter = new FilterDefinition();
            filter.setName(configDefinition.getConfigName());
            definedMap.put(configDefinition.getConfigName(), filter);
        }
        filter.getArgs().put(configDefinition.getConfigKey(), configDefinition.getConfigValue());
    }



}
